import javax.swing.*;
import javax.swing.border.*;
import java.security.PrivilegedAction;
import java.security.AccessController;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Dialog;

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.FactoryConfigurationError; 
import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;

//import org.xml.sax.SAXException; 
//import org.xml.sax.SAXParseException; 

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException; 
import java.io.FileWriter;

import org.w3c.dom.*;

import java.io.StringWriter;

public class HelloWorld extends JApplet implements ActionListener
{
	final static Dimension filler = new Dimension(5,5);

	//the xml docuement
	static Document document;

	//general purpose buffer
	String buffer;

	//the anntotationfilename
	String filename;
	
    //swing components	
	private JList componentsList;
	private DefaultListModel listModel;	
	private JPanel settingsPanel;
	private JButton upButton;
	private JButton downButton;
	private JButton editButton;
	private JButton saveButton;
	private JLabel statusLabel;
	private JButton previousButton;
	private JButton nextButton;
	
	
	public void init() {
		buffer = "Hello World \n";			
		filename = openFileDialog();
		XMLtoDocument(filename);		
		documentToListModel();
		initializeGUI();
	}
	private String openFileDialog(){
	
	FileDialog fd = new FileDialog(new Frame(), 
		"Select the annotation file",FileDialog.LOAD);
	fd.setFilenameFilter(new XMLFilenameFilter());
	//since the above line does not work in (all versions of) IE, the next one is added
	fd.setFile("*.xml");
	
	//these lines generate a security exception
	/*fd.setFilenameFilter(new FilenameFilter() { 
		public boolean accept(File dir, String name) { 
			return !name.endsWith(".xml"); } });
	*/
	
	
	fd.setVisible(true);	
	return fd.getDirectory() + fd.getFile();
	
	} 
	private void documentToListModel() {
		listModel = new DefaultListModel();
		if (document != null){		
			NodeList nodes = document.getElementsByTagName("core-component");			
			for (int i = 0;i < nodes.getLength();i++)
			{				
				listModel.addElement(
				  nodes.item(i).getAttributes().getNamedItem("den").getNodeValue());
			}
		}			

	
	}
	private void initializeGUI(){	
		
		getContentPane().setVisible(false);

		//main container
		JPanel mainVerticalPanel = new JPanel();
		mainVerticalPanel.setBackground(Color.white);
		mainVerticalPanel.setLayout(new BoxLayout(mainVerticalPanel,BoxLayout.Y_AXIS));
		
		
		//scrollable components list
		componentsList = new JList(listModel);
		componentsList.setPrototypeCellValue(
		"Purchase_ Order. Base Price5. Q3_ Q2_ Euro_ Amount");
		componentsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		JScrollPane listPane = new JScrollPane(componentsList);
		
		//A panel for the components list and the up and down buttons	
		JPanel listPanel = new JPanel();		
		listPanel.setBackground(Color.white);
		Border listPanelBorder = BorderFactory.createTitledBorder("Select Component");
		listPanel.setBorder(listPanelBorder);
		listPanel.add(listPane);
		
		listPanel.setMaximumSize(new Dimension(getContentPane().getSize().width,
						listPane.getSize().height+10));
				
		//move up and move down buttons
		upButton = new JButton("Move up");
		upButton.addActionListener(this);
		downButton = new JButton("Move down");
		downButton.addActionListener(this);
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setBackground(Color.white);
		buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.Y_AXIS));

		buttonPanel.add(upButton);
		buttonPanel.add(Box.createRigidArea(filler));
		buttonPanel.add(downButton);
		listPanel.add(buttonPanel);
		
		mainVerticalPanel.add(listPanel);
		
		//previouw, next, open and save buttons
		previousButton = new JButton("Previous super-element");
		previousButton.addActionListener(this);
		nextButton = new JButton("Next sub-element");
		nextButton.addActionListener(this);		
		editButton = new JButton("Edit Layout");
		editButton.addActionListener(this);
		saveButton = new JButton("Save");
		saveButton.addActionListener(this);
		
		JPanel buttonPanel2 = new JPanel();
		buttonPanel2.setBackground(Color.white);
		
		buttonPanel2.setLayout(new BoxLayout(buttonPanel2,BoxLayout.X_AXIS));
		buttonPanel2.add(previousButton);
		buttonPanel2.add(Box.createRigidArea(filler));
		buttonPanel2.add(nextButton);
		buttonPanel2.add(Box.createRigidArea(filler));
		buttonPanel2.add(editButton);
		buttonPanel2.add(Box.createRigidArea(filler));
		buttonPanel2.add(saveButton);
		
		mainVerticalPanel.add(Box.createRigidArea(filler));
		mainVerticalPanel.add(buttonPanel2);
				
		//A panel for the component settings
		settingsPanel = new JPanel();//new BorderLayout());
		settingsPanel.setBackground(Color.white);
		Border settingsPanelBorder = BorderFactory.createTitledBorder("Edit Layout");
		settingsPanel.setBorder(settingsPanelBorder);
		//settingsPanel.setLayout(new BoxLayout(settingsPanel,BoxLayout.Y_AXIS));
		
		
		mainVerticalPanel.add(Box.createRigidArea(filler));
		mainVerticalPanel.add(settingsPanel);
		
		//status label
		statusLabel = new JLabel(buffer);
		mainVerticalPanel.add(statusLabel);
		
		//this.getContentPane().doLayout();
		getContentPane().add(mainVerticalPanel);
		getContentPane().setVisible(true);
	}
	private void XMLtoDocument(String filename){
		try {
			//read xml file
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();			
			document = builder.parse(filename);			
			/*
			//code to transform xml to string:	
			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer();
			DOMSource source = new DOMSource(document);
			StringWriter sw = new StringWriter();
			StreamResult result = new StreamResult(sw);
			transformer.transform(source, result);
			buffer += sw.toString();
			*/
			buffer = "Succesfully read xml file";
		}
		catch (Exception e)
		{
			buffer = "Error: " + e;
		}
		
	}
	
	public String getXMLContent() 
	{
		return "String retrieved from applet: " + buffer;
	}

	public void actionPerformed(ActionEvent evt) 
	{
	if(evt.getSource() == saveButton) {
		statusLabel.setText("About to save file: " +filename);
		writeFile();
	}
	else if(evt.getSource() == upButton) {
		statusLabel.setText("Move component up");
		moveComponentUp();
	}
	else if(evt.getSource() == downButton) {
		statusLabel.setText("Move component down");
		moveComponentDown();
	}
	else if(evt.getSource() == editButton) {
		statusLabel.setText("Edit component");
		editComponent();
	}
	
	}
	private void editComponent() {
	//clear the settings panel.
	settingsPanel.removeAll();
	
	String sel = (String)componentsList.getSelectedValue();
	//statusLabel.setText("Editing component: " + sel);
    
	Node child = getElementByDen(sel).getFirstChild();
	//search the child notes for document settings
	while (child != null) {
		
		if (child.getNodeName() == "document-settings") {
			
			Node docSetting = child.getFirstChild();			
			while (docSetting != null) {
				if (docSetting.getNodeType() == Node.ELEMENT_NODE) {				
					JLabel t = new JLabel(docSetting.getNodeName());
					settingsPanel.add(t);				
				}
				docSetting = docSetting.getNextSibling();
			}
		child = null;
		}
		child = child.getNextSibling();
	}
	settingsPanel.invalidate();
	getContentPane().validate();
	
	}
	
		
	private void moveComponentUp() {
		int index = componentsList.getSelectedIndex();
		if (index != 0) {
			Object el = listModel.getElementAt(index);
			listModel.insertElementAt(el, index-1);
			listModel.remove(index+1);
			componentsList.setSelectedIndex(index -1);
			componentsList.ensureIndexIsVisible(index-1) ;
		}
	}
	
	private void moveComponentDown() {
		int index = componentsList.getSelectedIndex();
		if (index != listModel.getSize() -1) {
			Object el = listModel.getElementAt(index);
			listModel.insertElementAt(el, index+2);
			listModel.remove(index);
			componentsList.setSelectedIndex(index +1);
			componentsList.ensureIndexIsVisible(index+1) ;
		}
	}

	private String writeFile(){
		try {
			FileWriter aWriter = new FileWriter("test.txt", true);
			aWriter.write("blaat blaat");
			aWriter.flush();
			aWriter.close();    
			buffer = "succesfully wrote to file";							
			}
		catch(Exception e) {
			buffer = "Error: " + e;             				
		}
		statusLabel.setText(buffer);				
		return buffer;
    }
	
	public void showMessage(String s)
	{
	javax.swing.JOptionPane.showMessageDialog(getContentPane(),s) ;
	}
	
	private Node getElementByDen(String den) {
		
		if (document != null){		
			NodeList nodes = document.getElementsByTagName("core-component");			
			for (int i = 0;i < nodes.getLength();i++)
			{				
				if (nodes.item(i).getAttributes().
				getNamedItem("den").getNodeValue() == den)
				{
				return nodes.item(i);
				}
			}
			
		}
		return null;				
	}
class XMLFilenameFilter implements FilenameFilter {
	public boolean accept(File dir, String name) { 
		return name.endsWith(".xml"); 
	} 
}	


}

	







